package com.kstudio.ksnapshot.view;

import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.opengl.GLUtils;
import android.text.Layout;
import android.text.TextPaint;
import android.util.FloatMath;

import com.kstudio.ksnapshot.KUtil;

public class KDraw2D {
    private KUtil kLog = new KUtil("KSeekView");
    
    private FloatBuffer vertexBuffer;
    private FloatBuffer textureBuffer;
    private ByteBuffer indexBuffer;

    private int[] textures = new int[1];
    private int indiceslength;
    private int height;
    private int width;

    private float mx;
    private float my;
    private float MaxX;
    private int l;
    private int t;
    private int r;
    private int b;
    
    public KDraw2D() {
        height = 0;
        width = 0;
        mx = 0;
        my = 0;
        MaxX = 0;
        indiceslength = 0;
    }

    public void create(int l, int t, int r, int b) {
        this.l = l;
        this.t = t;
        this.r = r;
        this.b = b;
        height = t - b;
        width = r- l;

        float vertices[] = {
                (float) l, (float) b,
                (float) r, (float) b,
                (float) r, (float) t,
                (float) l, (float) t
            };

        float texture[] = { // texture reverse array
            0.0f, 1.0f,
            1.0f, 1.0f,
            1.0f, 0.0f,
            0.0f, 0.0f,
        };

        byte indices[] = {
            0,1,2,
            0,2,3
        };
        indiceslength = indices.length;

        ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
        byteBuf.order(ByteOrder.nativeOrder());
        vertexBuffer = byteBuf.asFloatBuffer();
        vertexBuffer.put(vertices);
        vertexBuffer.position(0);

        byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
        byteBuf.order(ByteOrder.nativeOrder());
        textureBuffer = byteBuf.asFloatBuffer();
        textureBuffer.put(texture);
        textureBuffer.position(0);

        indexBuffer = ByteBuffer.allocateDirect(indices.length);
        indexBuffer.put(indices);
        indexBuffer.position(0);
    }

    public void draw(GL10 gl) {
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        gl.glPushMatrix();
//        gl.glScalef(1f, 1f, 1f);
//        gl.glTranslatef(0f, 0f, 0f);
        gl.glTranslatef(mx, my, 0f);
        
        gl.glMatrixMode(GL10.GL_TEXTURE);
        gl.glLoadIdentity();

        // Draw
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

        gl.glFrontFace(GL10.GL_CCW);
        gl.glEnable(GL10.GL_CULL_FACE);
        gl.glCullFace(GL10.GL_BACK);

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

        gl.glDrawElements(GL10.GL_TRIANGLES, indiceslength, GL10.GL_UNSIGNED_BYTE, indexBuffer);

        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        gl.glDisable(GL10.GL_CULL_FACE);
        // Draw

        gl.glPopMatrix();
        gl.glLoadIdentity();
    }

    public void move(int x, int y) {
        kLog.d("move x = %d", x);
        if( x < 0 ) {
            this.mx = 0;
        } else if ( x > MaxX ) {
            this.mx = MaxX;
        } else {
            this.mx = (float) x;
        }
        
        this.my = (float) y;
    }

    public void loadTextureFromResourecID(GL10 gl, Context c, int id) {
        InputStream imagestream = c.getResources().openRawResource(id);
        Bitmap bitmap = null;

        try {
            bitmap = BitmapFactory.decodeStream(imagestream);
        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            try {
                imagestream.close();
                imagestream = null;
            } catch(Exception e) {
                e.printStackTrace();
            }
        }

        gl.glGenTextures(1, textures, 0);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);

        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

        height = bitmap.getHeight();
        width = bitmap.getWidth();
        bitmap.recycle();
    }

    public void loadTextureFromString(GL10 gl, int size, String s) {
        Bitmap bitmap;
        Canvas canvas;
        TextPaint paint;
        int textWidth;
        
        paint = new TextPaint();
        paint.setColor(0xff00ff00);
        paint.setTextSize(size);
        paint.setAntiAlias(false);
        paint.setTextScaleX(1);
        
        textWidth = (int) FloatMath.ceil(Layout.getDesiredWidth(s, (TextPaint) paint));
                
        Bitmap.Config config = Bitmap.Config.ARGB_8888;
        bitmap = Bitmap.createBitmap(textWidth, size, config);
        canvas = new Canvas(bitmap);
        bitmap.eraseColor(0);
        canvas.drawColor(0x00ffffff);
      
        canvas.drawText(s, 0, size, paint);
        
        gl.glGenTextures(1, textures, 0);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);

        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

        height = bitmap.getHeight();
        width = bitmap.getWidth();
        bitmap.recycle();
    }

    public int getHeight() {
        return height;
    }

    public int getWidth() {
        return width;
    }
    
    public int getLeft() {
        return l + (int)mx;
    }
    
    public int getRight() {
        return r + (int)mx;
    }
    
    public int getTop() {
        return t + (int)my;
    }
    
    public int getBottom() {
        return b + (int)my;
    }
    
    public int getCurrentPosX() {
        return (int)mx;
    }
    
    public void setMaxMoveXPos(int x) {
        kLog.d("setMaxMoveXPos = %d", x);
        this.MaxX = x;
    }
    

    public boolean checkIncludePosition(int x, int y) {
        kLog.e("left = %d right = %d", getLeft(), getRight());
        kLog.e("top = %d bottom = %d", getTop(), getBottom());
        if((getLeft() <= x) && (getRight() >= x) && (getTop() >= y) && (getBottom() <= y)) {
            return true;
        }
        return false;
    }
}
